"use strict";
/**
 * Element.matches()如果元素被指定的选择器字符串选择，Element.matches()  方法返回true; 否则返回false
 */
if (!Element.prototype.matches) {
    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
}
/**
 * Element.closest()匹配特定选择器且离当前元素最近的祖先元素（也可以是当前元素本身）。如果匹配不到，则返回null
 */
if (!Element.prototype.closest) {
    if (!Element.prototype.matches) {
        Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
    }
    Element.prototype.closest = function (s) {
        const el = this;
        let ancestor = this;
        //应该在作为搜索起点的祖先节点上调用contains()方法，并为该方法传递一个参数，即要检测的后代节点。如果传人的节点是当前节点的 后代，那么方法返回true;否则返回false。
        if (!document.documentElement.contains(el)) return null;
        do {
            if (ancestor.matches(s)) return ancestor;
            //parentElement只读属性返回指定元素的父元素
            ancestor = ancestor.parentElement;
        } while (ancestor !== null);
        return null;
    };
}
/**
 * 从 DOM 中删除元素 ES6 方式
 */
(function (elem) {
    for (let i = 0; i < elem.length; i++) {
        //in 判断对象是否是数组/对象的元素/属性
        if (!window[elem[i]] || 'remove' in window[elem[i]].prototype) continue;
        window[elem[i]].prototype.remove = function () {
            // removeChild() 方法可从子节点列表中删除某个节点。
            // 如删除成功，此方法可返回被删除的节点，如失败，则返回 NULL
            this.parentNode.removeChild(this);
        };
    }
})(['Element', 'CharacterData', 'DocumentType']);
// 用于智能动画的请求动画帧
(function () {
    let lastTime = 0;
    const vendors = ['webkit', 'moz'];
    //window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画，并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
    // 该方法需要传入一个回调函数作为参数，该回调函数会在浏览器下一次重绘之前执行
    for (let x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
        //cancelAnimationFrame()方法用于取消以前通过对window.requestAnimationFrame()的调用计划的动画帧请求
        window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
    }
    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function (callback) {
            //返回当前时间毫秒数
            const currTime = new Date().getTime();
            //Math.max() 函数返回一组数中的最大值
            const timeToCall = Math.max(0, 16 - (currTime - lastTime));
            //setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式
            const id = window.setTimeout(function () {
                callback(currTime + timeToCall);
            }, timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };
    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function (id) {
            //clearTimeout() 方法可取消由 setTimeout() 方法设置的 timeout
            clearTimeout(id);
        };
}());
(function (arr) {
    //forEach() 方法对数组的每个元素执行一次提供的函数
    arr.forEach(function (item) {
        //hasOwnProperty() 方法会返回一个布尔值，表明对象自身属性中是否具有指定的属性（也就是，是否有指定的键）
        if (item.hasOwnProperty('prepend')) {
            return;
        }
        //Object.defineProperty() 方法会直接在一个对象上定义一个新属性，或者修改一个对象的现有属性，并返回此对象
        Object.defineProperty(item, 'prepend', {
            configurable: true,
            enumerable: true,
            writable: true,
            value: function prepend() {
                //能将有length属性的对象转换为数组
                const argArr = Array.prototype.slice.call(arguments),
                    //createDocumentFragment()方法创建了一虚拟的节点对象，节点对象包含所有属性和方法 该方法还可以更安全改变文档的结构及节点
                    docFrag = document.createDocumentFragment();
                argArr.forEach(function (argItem) {
                    //instanceof运算符用来判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上
                    const isNode = argItem instanceof Node;
                    //appendChild() 方法向节点添加最后一个子节点
                    //createTextNode() 可创建文本节点
                    docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem)));
                });
                //insertBefore() 方法在指定的已有子节点之前插入新的子节点
                this.insertBefore(docFrag, this.firstChild);
            }
        });
    });
})([Element.prototype, Document.prototype, DocumentFragment.prototype]);
//getAttributeNames()方法 以字符串的形式Element返回元素的属性名称 Array 如果元素没有属性，则返回一个空数组。
if (Element.prototype.getAttributeNames == undefined) {
    Element.prototype.getAttributeNames = function () {
        const attributes = this.attributes;
        const length = attributes.length;
        const result = new Array(length);
        for (let i = 0; i < length; i++) {
            result[i] = attributes[i].name;
        }
        return result;
    };
}
// 全局变量
window.KTUtilElementDataStore = {};
window.KTUtilElementDataStoreID = 0;
window.KTUtilDelegatedEventHandlers = {};
const KTUtil = function () {
    const resizeHandlers = [];
    /** @type {object} 设备宽度断点 **/
    let breakpoints = {
        sm: 544, // 小屏幕/手机
        md: 768, // 中屏幕/平板电脑
        lg: 992, // 大屏幕/桌面
        xl: 1200 // 超大屏幕/宽桌面
    };
    /**
     *使用一些完成调整大小后附加事件处理程序的延迟
     */
    let _runResizeHandlers;
    const _windowResizeHandler = function () {
        _runResizeHandlers = function () {
            // 重新初始化其他订阅的元素
            for (let i = 0; i < resizeHandlers.length; i++) {
                const each = resizeHandlers[i];
                each.call();
            }
        };
        let timer;
        //addEventListener() 方法用于向指定元素添加事件句柄
        window.addEventListener('resize', function () {
            //节流功能：作为需要节流的功能输入，延迟是以毫秒为单位的时间间隔
            KTUtil.throttle(timer, function () {
                _runResizeHandlers();
            }, 200);
        });
    };
    return {
        /**
         * 类 主初始值设定项
         * @param {object} settings.
         * @returns null
         */
        //启动主题的主要功能
        init: function (settings) {
            if (settings && settings.breakpoints) {
                breakpoints = settings.breakpoints;
            }
            _windowResizeHandler();
        },
        /**
         * 添加窗口大小调整事件处理程序。
         * @param {function} callback function.
         */
        addResizeHandler: function (callback) {
            resizeHandlers.push(callback);
        },
        /**
         * 删除窗口大小调整事件处理程序。
         * @param {function} callback function.
         */
        removeResizeHandler: function (callback) {
            for (let i = 0; i < resizeHandlers.length; i++) {
                if (callback === resizeHandlers[i]) {
                    delete resizeHandlers[i];
                }
            }
        },
        /**
         * 触发窗口大小调整处理程序。
         */
        runResizeHandlers: function () {
            _runResizeHandlers();
        },
        resize: function () {
            if (typeof (Event) === 'function') {
                // 当代浏览器 dispatchEvent 用于高级浏览器(如Chrome、Firefox等)的事件触发
                window.dispatchEvent(new Event('resize'));
            } else {
                //适用于IE和其他旧浏览器
                //在现代浏览器上导致弃用警告
                //createEvent 方法创建新的 Event 对象
                const evt = window.document.createEvent('UIEvents');
                //initEvent() 方法初始化新事件对象的属性
                evt.initUIEvent('resize', true, false, window, 0);
                window.dispatchEvent(evt);
            }
        },
        /**
         * 从URL获取参数值
         * @param {string} paramName 参数名
         * @returns {string}
         */
        getURLParam: function (paramName) {
            //window.location.search.substring(1) 查询(参数)部分 得到的是url中？部分。
            let searchString = window.location.search.substring(1), i, val, params = searchString.split("&");
            for (i = 0; i < params.length; i++) {
                val = params[i].split("=");
                if (val[0] == paramName) {
                    return unescape(val[1]);
                }
            }
            return null;
        },
        /**
         * 检查当前设备是否为移动触摸
         * @returns {boolean}
         */
        isMobileDevice: function () {
            //(this.getViewPort().width < this.getBreakpoint('lg') ? true : false);
            let test = (this.getViewPort().width < this.getBreakpoint('lg'));
            if (test === false) {
                // 用于普通web客户端
                test = navigator.userAgent.match(/iPad/i) != null;
            }
            return test;
        },
        /**
         * 检查当前设备是否为桌面设备
         * @returns {boolean}
         */
        isDesktopDevice: function () {
            //KTUtil.isMobileDevice() ? false : true;
            return !KTUtil.isMobileDevice();
        },
        /**
         * 浏览器窗口内的空间称为“视口”，受显示器分辨率、浏览器中正在使用的工具栏数量以及浏览器是全屏还是窗口模式的影响
         * 获取浏览器窗口视口大小
         * @returns {object}
         */
        getViewPort: function () {
            //window 它代表浏览器的窗口
            let e = window,
                a = 'inner';
            if (!('innerWidth' in window)) {
                a = 'client';
                //documentElement 属性以一个元素对象返回一个文档的文档元素 body 属性用于设置或返回文档体
                e = document.documentElement || document.body;
            }
            return {
                width: e[a + 'Width'],
                height: e[a + 'Height']
            };
        },
        /**
         * 检查给定的设备模式当前是否激活
         * @param {string} mode 响应模式名称（例如：桌面、台式机和平板电脑、平板电脑、平板电脑和移动设备、移动设备）
         * @returns {boolean}
         */
        isInResponsiveRange: function (mode) {
            const breakpoint = this.getViewPort().width;
            if (mode == 'general') {
                return true;
            } else if (mode == 'desktop' && breakpoint >= (this.getBreakpoint('lg') + 1)) {
                return true;
            } else if (mode == 'tablet' && (breakpoint >= (this.getBreakpoint('md') + 1) && breakpoint < this.getBreakpoint('lg'))) {
                return true;
            } else if (mode == 'mobile' && breakpoint <= this.getBreakpoint('md')) {
                return true;
            } else if (mode == 'desktop-and-tablet' && breakpoint >= (this.getBreakpoint('md') + 1)) {
                return true;
            } else if (mode == 'tablet-and-mobile' && breakpoint <= this.getBreakpoint('lg')) {
                return true;
            } else if (mode == 'minimal-desktop-and-below' && breakpoint <= this.getBreakpoint('xl')) {
                return true;
            }
            return false;
        },
        /**
         * 检查给定的设备模式当前是否激活
         * @param {string} mode 响应模式名称（例如：桌面、台式机和平板电脑、平板电脑、平板电脑和移动设备、移动设备）
         * @returns {boolean}
         */
        isBreakpointUp: function (mode) {
            const width = this.getViewPort().width;
            const breakpoint = this.getBreakpoint(mode);
            return (width >= breakpoint);
        },
        isBreakpointDown: function (mode) {
            const width = this.getViewPort().width;
            const breakpoint = this.getBreakpoint(mode);
            return (width < breakpoint);
        },
        /**
         * 为给定前缀生成唯一ID
         * @param {string} prefix 生成的ID的前缀
         * @returns {string}
         */
        getUniqueID: function (prefix) {
            return prefix + Math.floor(Math.random() * (new Date()).getTime());
        },
        /**
         * 获取给定断点模式的窗口宽度
         * @param {string} mode 模式响应模式名称（例如：xl、lg、md、sm）
         * @returns {number}
         */
        getBreakpoint: function (mode) {
            return breakpoints[mode];
        },
        /**
         * 检查对象是否具有与给定密钥路径匹配的属性
         * @param {object} obj 对象包含与给定键路径成对的值
         * @param {object} keys 用点分隔的关键点路径
         * @returns {object}
         */
        isset: function (obj, keys) {
            let stone;
            keys = keys || '';
            if (keys.indexOf('[') !== -1) {
                throw new Error('Unsupported object path notation.');
            }
            keys = keys.split('.');
            do {
                if (obj === undefined) {
                    return false;
                }
                stone = keys.shift();
                //hasOwnProperty() 方法会返回一个布尔值，表明对象自身属性中是否具有指定的属性（也就是，是否有指定的键）
                if (!obj.hasOwnProperty(stone)) {
                    return false;
                }
                obj = obj[stone];
            } while (keys.length);
            return true;
        },
        /**
         * 获取给定元素父级的最高z-index
         * @param {object} el jQuery元素对象
         * @returns {number}
         */
        getHighestZindex: function (el) {
            let position, value;
            while (el && el !== document) {
                //如果位置设置为浏览器忽略z-index的值，则忽略z-index
                //这使得该函数的行为在浏览器之间保持一致
                //如果元素已定位，WebKit始终返回自动
                position = KTUtil.css(el, 'position');
                if (position === "absolute" || position === "relative" || position === "fixed") {
                    //未指定zIndex时，IE返回0
                    //其他浏览器返回字符串
                    //我们忽略显式值为0的嵌套元素的情况
                    // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
                    value = parseInt(KTUtil.css(el, 'z-index'));
                    if (!isNaN(value) && value !== 0) {
                        return value;
                    }
                }
                el = el.parentNode;
            }
            return null;
        },
        /**
         * 检查元素是否有固定位置FREG的父元素
         * @param {object} el jQuery元素对象
         * @returns {boolean}
         */
        hasFixedPositionedParent: function (el) {
            let position;
            while (el && el !== document) {
                position = KTUtil.css(el, 'position');
                if (position === "fixed") {
                    return true;
                }
                //parentNode 属性以 Node 对象的形式返回指定节点的父节点
                el = el.parentNode;
            }
            return false;
        },
        /**
         * 模拟延迟
         */
        sleep: function (milliseconds) {
            const start = new Date().getTime();
            for (let i = 0; i < 1e7; i++) {
                if ((new Date().getTime() - start) > milliseconds) {
                    break;
                }
            }
        },
        /**
         * 获取给定最小值和最大值范围内随机生成的整数值
         * @param {number} min 范围起始值
         * @param {number} max 范围结束值
         * @returns {number}
         */
        getRandomInt: function (min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        },
        /**
         * 检查是否包含角度库
         * @returns {boolean}
         */
        isAngularVersion: function () {
            //window.Zone !== undefined ? true : false
            return window.Zone !== undefined;
        },
        // 深度扩展:  $.extend(true, {}, objA, objB);
        deepExtend: function (out) {
            out = out || {};
            for (let i = 1; i < arguments.length; i++) {
                const obj = arguments[i];
                if (!obj) continue;
                for (const key in obj) {
                    if (!obj.hasOwnProperty(key)) {
                        continue;
                    }
                    // Object.prototype.toString.call 检测对象类型
                    if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
                        out[key] = KTUtil.deepExtend(out[key], obj[key]);
                        continue;
                    }
                    out[key] = obj[key];
                }
            }
            return out;
        },
        // 延伸:  $.extend({}, objA, objB);
        extend: function (out) {
            out = out || {};
            for (let i = 1; i < arguments.length; i++) {
                if (!arguments[i])
                    continue;
                for (const key in arguments[i]) {
                    if (arguments[i].hasOwnProperty(key))
                        out[key] = arguments[i][key];
                }
            }
            return out;
        },
        getById: function (el) {
            if (typeof el === 'string') {
                //getElementById() 方法可返回对拥有指定 ID 的第一个对象的引用
                return document.getElementById(el);
            } else {
                return el;
            }
        },
        getByTag: function (query) {
            //getElementsByTagName() 方法可返回带有指定标签名的对象的集合
            return document.getElementsByTagName(query);
        },
        getByTagName: function (query) {
            return document.getElementsByTagName(query);
        },
        getByClass: function (query) {
            //getElementsByClassName() 方法返回文档中所有指定类名的元素集合，作为 NodeList 对象
            return document.getElementsByClassName(query);
        },
        getBody: function () {
            return document.getElementsByTagName('body')[0];
        },
        /**
         * 检查元素是否具有给定的类
         * @param {object} el jQuery元素对象
         * @param classes
         * @returns {boolean}
         */
        hasClasses: function (el, classes) {
            if (!el) {
                return;
            }
            const classesArr = classes.split(" ");
            for (let i = 0; i < classesArr.length; i++) {
                if (KTUtil.hasClass(el, KTUtil.trim(classesArr[i])) == false) {
                    return false;
                }
            }
            return true;
        },
        hasClass: function (el, className) {
            if (!el) {
                return;
            }
            //test() 方法用于检测一个字符串是否匹配某个模式
            return el.classList ? el.classList.contains(className) : new RegExp('\\b' + className + '\\b').test(el.className);
        },
        addClass: function (el, className) {
            if (!el || typeof className === 'undefined') {
                return;
            }
            const classNames = className.split(' ');
            if (el.classList) {
                for (let i = 0; i < classNames.length; i++) {
                    if (classNames[i] && classNames[i].length > 0) {
                        el.classList.add(KTUtil.trim(classNames[i]));
                    }
                }
            } else if (!KTUtil.hasClass(el, className)) {
                for (let x = 0; x < classNames.length; x++) {
                    el.className += ' ' + KTUtil.trim(classNames[x]);
                }
            }
        },
        removeClass: function (el, className) {
            if (!el || typeof className === 'undefined') {
                return;
            }
            const classNames = className.split(' ');
            if (el.classList) {
                for (let i = 0; i < classNames.length; i++) {
                    el.classList.remove(KTUtil.trim(classNames[i]));
                }
            } else if (KTUtil.hasClass(el, className)) {
                for (let x = 0; x < classNames.length; x++) {
                    el.className = el.className.replace(new RegExp('\\b' + KTUtil.trim(classNames[x]) + '\\b', 'g'), '');
                }
            }
        },
        triggerCustomEvent: function (el, eventName, data) {
            let event;
            if (window.CustomEvent) {
                event = new CustomEvent(eventName, {
                    detail: data
                });
            } else {
                event = document.createEvent('CustomEvent');
                event.initCustomEvent(eventName, true, true, data);
            }
            el.dispatchEvent(event);
        },
        triggerEvent: function (node, eventName) {
            let event;
            // 确保使用所提供节点的ownerDocument以避免跨窗口问题
            let doc;
            if (node.ownerDocument) {
                doc = node.ownerDocument;
            } else if (node.nodeType == 9) {
                //节点可以是文档本身，nodeType 9 = DOCUMENT_NODE
                doc = node;
            } else {
                throw new Error("Invalid node passed to fireEvent: " + node.id);
            }
            if (node.dispatchEvent) {
                // 壁虎式的方法（现在的标准）需要更多的工作
                let eventClass = "";
                // 不同的事件具有不同的事件类
                // 如果此开关语句无法将eventName映射到eventClass，事件触发将失败。
                switch (eventName) {
                    // 在Safari中，“click”的调度似乎无法正常工作。改用“mousedown”或“mouseup”
                    case "click":
                    case "mouseenter":
                    case "mouseleave":
                    case "mousedown":
                    case "mouseup":
                        eventClass = "MouseEvents";
                        break;
                    case "focus":
                    case "change":
                    case "blur":
                    case "select":
                        eventClass = "HTMLEvents";
                        break;
                    default:
                        throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
                }
                event = doc.createEvent(eventClass);
                const bubbles = eventName == "change" ? false : true;
                // 创建为冒泡且可取消的所有事件
                event.initEvent(eventName, bubbles, true);
                // 允许检测合成事件
                event.synthetic = true;
                // 第二个参数表示继续执行默认操作
                node.dispatchEvent(event, true);
            } else if (node.fireEvent) {
                // IE老派风格
                event = doc.createEventObject();
                // 允许检测合成事件
                event.synthetic = true;
                node.fireEvent("on" + eventName, event);
            }
        },
        index: function (el) {
            let c = el.parentNode.children, i = 0;
            for (; i < c.length; i++)
                if (c[i] == el) return i;
        },
        trim: function (string) {
            return string.trim();
        },
        eventTriggered: function (e) {
            if (e.currentTarget.dataset.triggered) {
                return true;
            } else {
                e.currentTarget.dataset.triggered = true;
                return false;
            }
        },
        remove: function (el) {
            if (el && el.parentNode) {
                el.parentNode.removeChild(el);
            }
        },
        find: function (parent, query) {
            parent = KTUtil.getById(parent);
            if (parent) {
                return parent.querySelector(query);
            }
        },
        findAll: function (parent, query) {
            parent = KTUtil.getById(parent);
            if (parent) {
                return parent.querySelectorAll(query);
            }
        },
        insertAfter: function (el, referenceNode) {
            return referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
        },
        parents: function (elem, selector) {
            if (!Element.prototype.matches) {
                Element.prototype.matches =
                    Element.prototype.matchesSelector ||
                    Element.prototype.mozMatchesSelector ||
                    Element.prototype.msMatchesSelector ||
                    Element.prototype.oMatchesSelector ||
                    Element.prototype.webkitMatchesSelector ||
                    function (s) {
                        let matches = (this.document || this.ownerDocument).querySelectorAll(s), i = matches.length;
                        //while (--i >= 0 && matches.item(i) !== this) {}
                        return i > -1;
                    };
            }
            // 设置父数组
            const parents = [];
            // 将每个父元素推送到数组中
            for (; elem && elem !== document; elem = elem.parentNode) {
                if (selector) {
                    if (elem.matches(selector)) {
                        parents.push(elem);
                    }
                    continue;
                }
                parents.push(elem);
            }
            // 返回父数组
            return parents;
        },
        children: function (el, selector, log) {
            if (!el || !el.childNodes) {
                return;
            }
            let result = [],
                i = 0,
                l = el.childNodes.length;
            for (i; i < l; ++i) {
                if (el.childNodes[i].nodeType == 1 && KTUtil.matches(el.childNodes[i], selector, log)) {
                    result.push(el.childNodes[i]);
                }
            }
            return result;
        },
        child: function (el, selector, log) {
            const children = KTUtil.children(el, selector, log);
            return children ? children[0] : null;
        },
        matches: function (el, selector, log) {
            const p = Element.prototype;
            const f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function (s) {
                return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
            };
            if (el && el.tagName) {
                return f.call(el, selector);
            } else {
                return false;
            }
        },
        data: function (el) {
            return {
                set: function (name, data) {
                    if (!el) {
                        return;
                    }
                    if (el.customDataTag === undefined) {
                        window.KTUtilElementDataStoreID++;
                        el.customDataTag = window.KTUtilElementDataStoreID;
                    }
                    if (window.KTUtilElementDataStore[el.customDataTag] === undefined) {
                        window.KTUtilElementDataStore[el.customDataTag] = {};
                    }
                    window.KTUtilElementDataStore[el.customDataTag][name] = data;
                },
                get: function (name) {
                    if (!el) {
                        return;
                    }
                    if (el.customDataTag === undefined) {
                        return null;
                    }
                    return this.has(name) ? window.KTUtilElementDataStore[el.customDataTag][name] : null;
                },
                has: function (name) {
                    if (!el) {
                        return false;
                    }
                    if (el.customDataTag === undefined) {
                        return false;
                    }
                    //(window.KTUtilElementDataStore[el.customDataTag] && window.KTUtilElementDataStore[el.customDataTag][name]) ? true : false
                    return !!(window.KTUtilElementDataStore[el.customDataTag] && window.KTUtilElementDataStore[el.customDataTag][name]);
                },
                remove: function (name) {
                    if (el && this.has(name)) {
                        delete window.KTUtilElementDataStore[el.customDataTag][name];
                    }
                }
            };
        },
        outerWidth: function (el, margin) {
            let width;
            if (margin === true) {
                width = parseFloat(el.offsetWidth);
                width += parseFloat(KTUtil.css(el, 'margin-left')) + parseFloat(KTUtil.css(el, 'margin-right'));
                return parseFloat(width);
            } else {
                width = parseFloat(el.offsetWidth);
                return width;
            }
        },
        offset: function (el) {
            let rect, win;
            if (!el) {
                return;
            }
            // 断开和隐藏（显示：无）元素返回零（gh-2310）
            // 支持：仅IE<=11
            // 在服务器上运行getBoundingClientRect
            // IE中断开连接的节点抛出错误
            if (!el.getClientRects().length) {
                return {top: 0, left: 0};
            }
            // 通过将视口滚动添加到视口相对gBCR获取文档相对位置
            rect = el.getBoundingClientRect();
            win = el.ownerDocument.defaultView;
            return {
                top: rect.top + win.pageYOffset,
                left: rect.left + win.pageXOffset
            };
        },
        height: function (el) {
            return KTUtil.css(el, 'height');
        },
        outerHeight: function (el, withMargin) {
            let height = el.offsetHeight;
            let style;
            if (typeof withMargin !== 'undefined' && withMargin === true) {
                style = getComputedStyle(el);
                height += parseInt(style.marginTop) + parseInt(style.marginBottom);
                return height;
            } else {
                return height;
            }
        },
        visible: function (el) {
            return !(el.offsetWidth === 0 && el.offsetHeight === 0);
        },
        attr: function (el, name, value) {
            if (el == undefined) {
                return;
            }
            if (value !== undefined) {
                el.setAttribute(name, value);
            } else {
                return el.getAttribute(name);
            }
        },
        hasAttr: function (el, name) {
            if (el == undefined) {
                return;
            }
            //el.getAttribute(name) ? true : false
            return !!el.getAttribute(name);
        },
        removeAttr: function (el, name) {
            if (el == undefined) {
                return;
            }
            el.removeAttribute(name);
        },
        animate: function (from, to, duration, update, easing, done) {
            // 开始动画循环
            const start = window.performance && window.performance.now ? window.performance.now() : +new Date();
            /**
             * TinyAnimate.easings
             * 改编自jQuery
             */
            const easings = {};
            easings.linear = function (t, b, c, d) {
                return c * t / d + b;
            };
            let easing2 = easings.linear;
            // 如果调用不正确，则提前纾困
            if (typeof from !== 'number' ||
                typeof to !== 'number' ||
                typeof duration !== 'number' ||
                typeof update !== 'function') {
                return;
            }
            // 如有必要，创建mock done（）函数
            if (typeof done !== 'function') {
                done = function () {
                };
            }
            // Pick implementation (requestAnimationFrame | setTimeout)
            const rAF = window.requestAnimationFrame || function (callback) {
                window.setTimeout(callback, 1000 / 50);
            };
            // 动画循环
            const canceled = false;
            const change = to - from;

            function loop(timestamp) {
                const time = (timestamp || +new Date()) - start;
                if (time >= 0) {
                    update(easing2(time, from, change, duration));
                }
                if (time >= 0 && time >= duration) {
                    update(to);
                    done();
                } else {
                    rAF(loop);
                }
            }

            update(from);
            rAF(loop);
        },
        actualCss: function (el, prop, cache) {
            let css = '';
            //el instanceof HTMLElement === false
            if (!(el instanceof HTMLElement)) {
                return;
            }
            if (!el.getAttribute('kt-hidden-' + prop) || cache === false) {
                let value;
                //元素是隐藏的，因此： 制作el块，这样我们可以测量它的高度，但仍然可以隐藏
                css = el.style.cssText;
                el.style.cssText = 'position: absolute; visibility: hidden; display: block;';
                if (prop == 'width') {
                    value = el.offsetWidth;
                } else if (prop == 'height') {
                    value = el.offsetHeight;
                }
                el.style.cssText = css;
                // 将其存储在缓存中
                el.setAttribute('kt-hidden-' + prop, value);
                return parseFloat(value);
            } else {
                // 将其存储在缓存中
                return parseFloat(el.getAttribute('kt-hidden-' + prop));
            }
        },
        actualHeight: function (el, cache) {
            return KTUtil.actualCss(el, 'height', cache);
        },
        actualWidth: function (el, cache) {
            return KTUtil.actualCss(el, 'width', cache);
        },
        getScroll: function (element, method) {
            // 传入的'method'值应为'Top'或'Left'
            method = 'scroll' + method;
            return (element == window || element == document) ? (
                self[(method == 'scrollTop') ? 'pageYOffset' : 'pageXOffset'] ||
                // eslint-disable-next-line no-undef
                (browserSupportsBoxModel && document.documentElement[method]) ||
                document.body[method]
            ) : element[method];
        },
        css: function (el, styleProp, value) {
            if (!el) {
                return;
            }
            if (value !== undefined) {
                el.style[styleProp] = value;
            } else {
                const defaultView = (el.ownerDocument || document).defaultView;
                // W3C标准方式：
                if (defaultView && defaultView.getComputedStyle) {
                    // 将属性名称清理为css符号
                    // （用连字符分隔的单词，如字体大小 font-Size）
                    styleProp = styleProp.replace(/([A-Z])/g, "-$1").toLowerCase();
                    return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
                } else if (el.currentStyle) { // IE
                    // 将属性名称清理为camelCase
                    //styleProp = styleProp.replace(/\-(\w)/g, function (str, letter) {
                    styleProp = styleProp.replace(/-(\w)/g, function (str, letter) {
                        return letter.toUpperCase();
                    });
                    value = el.currentStyle[styleProp];
                    // 将IE上的其他单位转换为像素
                    if (/^\d+(em|pt|%|ex)?$/i.test(value)) {
                        return (function (value) {
                            const oldLeft = el.style.left,
                                oldRsLeft = el.runtimeStyle.left;
                            el.runtimeStyle.left = el.currentStyle.left;
                            el.style.left = value || 0;
                            value = el.style.pixelLeft + "px";
                            el.style.left = oldLeft;
                            el.runtimeStyle.left = oldRsLeft;
                            return value;
                        })(value);
                    }
                    return value;
                }
            }
        },
        slide: function (el, dir, speed, callback, recalcMaxHeight) {
            if (!el || (dir == 'up' && KTUtil.visible(el) === false) || (dir == 'down' && KTUtil.visible(el) === true)) {
                return;
            }
            speed = (speed ? speed : 600);
            const calcHeight = KTUtil.actualHeight(el);
            let calcPaddingTop = false;
            let calcPaddingBottom = false;
            if (KTUtil.css(el, 'padding-top') && KTUtil.data(el).has('slide-padding-top') !== true) {
                KTUtil.data(el).set('slide-padding-top', KTUtil.css(el, 'padding-top'));
            }
            if (KTUtil.css(el, 'padding-bottom') && KTUtil.data(el).has('slide-padding-bottom') !== true) {
                KTUtil.data(el).set('slide-padding-bottom', KTUtil.css(el, 'padding-bottom'));
            }
            if (KTUtil.data(el).has('slide-padding-top')) {
                calcPaddingTop = parseInt(KTUtil.data(el).get('slide-padding-top'));
            }
            if (KTUtil.data(el).has('slide-padding-bottom')) {
                calcPaddingBottom = parseInt(KTUtil.data(el).get('slide-padding-bottom'));
            }
            if (dir == 'up') {
                el.style.cssText = 'display: block; overflow: hidden;';
                if (calcPaddingTop) {
                    KTUtil.animate(0, calcPaddingTop, speed, function (value) {
                        el.style.paddingTop = (calcPaddingTop - value) + 'px';
                    }, 'linear');
                }
                if (calcPaddingBottom) {
                    KTUtil.animate(0, calcPaddingBottom, speed, function (value) {
                        el.style.paddingBottom = (calcPaddingBottom - value) + 'px';
                    }, 'linear');
                }
                KTUtil.animate(0, calcHeight, speed, function (value) {
                    el.style.height = (calcHeight - value) + 'px';
                }, 'linear', function () {
                    el.style.height = '';
                    el.style.display = 'none';
                    if (typeof callback === 'function') {
                        callback();
                    }
                });
            } else if (dir == 'down') {
                el.style.cssText = 'display: block; overflow: hidden;';
                if (calcPaddingTop) {
                    KTUtil.animate(0, calcPaddingTop, speed, function (value) {
                        el.style.paddingTop = value + 'px';
                    }, 'linear', function () {
                        el.style.paddingTop = '';
                    });
                }
                if (calcPaddingBottom) {
                    KTUtil.animate(0, calcPaddingBottom, speed, function (value) {
                        el.style.paddingBottom = value + 'px';
                    }, 'linear', function () {
                        el.style.paddingBottom = '';
                    });
                }
                KTUtil.animate(0, calcHeight, speed, function (value) {
                    el.style.height = value + 'px';
                }, 'linear', function () {
                    el.style.height = '';
                    el.style.display = '';
                    el.style.overflow = '';
                    if (typeof callback === 'function') {
                        callback();
                    }
                });
            }
        },
        slideUp: function (el, speed, callback) {
            KTUtil.slide(el, 'up', speed, callback);
        },
        slideDown: function (el, speed, callback) {
            KTUtil.slide(el, 'down', speed, callback);
        },
        show: function (el, display) {
            if (typeof el !== 'undefined') {
                el.style.display = (display ? display : 'block');
            }
        },
        hide: function (el) {
            if (typeof el !== 'undefined') {
                el.style.display = 'none';
            }
        },
        addEvent: function (el, type, handler, one) {
            if (typeof el !== 'undefined' && el !== null) {
                el.addEventListener(type, handler);
            }
        },
        removeEvent: function (el, type, handler) {
            if (el !== null) {
                el.removeEventListener(type, handler);
            }
        },
        on: function (element, selector, event, handler) {
            if (!selector) {
                return;
            }
            const eventId = KTUtil.getUniqueID('event');
            window.KTUtilDelegatedEventHandlers[eventId] = function (e) {
                const targets = element.querySelectorAll(selector);
                let target = e.target;
                while (target && target !== element) {
                    let i = 0, j = targets.length;
                    for (; i < j; i++) {
                        if (target === targets[i]) {
                            handler.call(target, e);
                        }
                    }
                    target = target.parentNode;
                }
            }
            KTUtil.addEvent(element, event, window.KTUtilDelegatedEventHandlers[eventId]);
            return eventId;
        },
        off: function (element, event, eventId) {
            if (!element || !window.KTUtilDelegatedEventHandlers[eventId]) {
                return;
            }
            KTUtil.removeEvent(element, event, window.KTUtilDelegatedEventHandlers[eventId]);
            delete window.KTUtilDelegatedEventHandlers[eventId];
        },
        one: function onetime(el, type, callback) {
            el.addEventListener(type, function callee(e) {
                // 删除事件
                if (e.target && e.target.removeEventListener) {
                    e.target.removeEventListener(e.type, callee);
                }
                if (el && el.removeEventListener) {
                    e.currentTarget.removeEventListener(e.type, callee);
                }
                //调用处理
                return callback(e);
            });
        },
        hash: function (str) {
            let hash = 0, i, chr;
            if (str.length === 0) return hash;
            for (i = 0; i < str.length; i++) {
                chr = str.charCodeAt(i);
                hash = ((hash << 5) - hash) + chr;
                //转换为32位整数
                hash |= 0;
            }
            return hash;
        },
        animateClass: function (el, animationName, callback) {
            let animation;
            const animations = {
                animation: 'animationend',
                OAnimation: 'oAnimationEnd',
                MozAnimation: 'mozAnimationEnd',
                WebkitAnimation: 'webkitAnimationEnd',
                msAnimation: 'msAnimationEnd',
            };
            for (const t in animations) {
                if (el.style[t] !== undefined) {
                    animation = animations[t];
                }
            }
            KTUtil.addClass(el, 'animated ' + animationName);
            KTUtil.one(el, animation, function () {
                KTUtil.removeClass(el, 'animated ' + animationName);
            });
            if (callback) {
                KTUtil.one(el, animation, callback);
            }
        },
        transitionEnd: function (el, callback) {
            let transition;
            const transitions = {
                transition: 'transitionend',
                OTransition: 'oTransitionEnd',
                MozTransition: 'mozTransitionEnd',
                WebkitTransition: 'webkitTransitionEnd',
                msTransition: 'msTransitionEnd'
            };
            for (const t in transitions) {
                if (el.style[t] !== undefined) {
                    transition = transitions[t];
                }
            }
            KTUtil.one(el, transition, callback);
        },
        animationEnd: function (el, callback) {
            let animation;
            const animations = {
                animation: 'animationend',
                OAnimation: 'oAnimationEnd',
                MozAnimation: 'mozAnimationEnd',
                WebkitAnimation: 'webkitAnimationEnd',
                msAnimation: 'msAnimationEnd'
            };
            for (const t in animations) {
                if (el.style[t] !== undefined) {
                    animation = animations[t];
                }
            }
            KTUtil.one(el, animation, callback);
        },
        animateDelay: function (el, value) {
            const vendors = ['webkit-', 'moz-', 'ms-', 'o-', ''];
            for (let i = 0; i < vendors.length; i++) {
                KTUtil.css(el, vendors[i] + 'animation-delay', value);
            }
        },
        animateDuration: function (el, value) {
            const vendors = ['webkit-', 'moz-', 'ms-', 'o-', ''];
            for (let i = 0; i < vendors.length; i++) {
                KTUtil.css(el, vendors[i] + 'animation-duration', value);
            }
        },
        scrollTo: function (target, offset, duration) {
            const duration2 = duration ? duration : 500;
            const targetPos = target ? KTUtil.offset(target).top : 0;
            let scrollPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
            let from, to;
            if (offset) {
                scrollPos += offset;
            }
            from = scrollPos;
            to = targetPos;
            KTUtil.animate(from, to, duration2, function (value) {
                document.documentElement.scrollTop = value;
                document.body.parentNode.scrollTop = value;
                document.body.scrollTop = value;
            }); //, easing, done
        },
        scrollTop: function (offset, duration) {
            KTUtil.scrollTo(null, offset, duration);
        },
        isArray: function (obj) {
            return obj && Array.isArray(obj);
        },
        ready: function (callback) {
            if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
                callback();
            } else {
                document.addEventListener('DOMContentLoaded', callback);
            }
        },
        isEmpty: function (obj) {
            for (const prop in obj) {
                if (obj.hasOwnProperty(prop)) {
                    return false;
                }
            }
            return true;
        },
        numberString: function (nStr) {
            nStr += '';
            const x = nStr.split('.');
            let x1 = x[0];
            const x2 = x.length > 1 ? '.' + x[1] : '';
            const rgx = /(\d+)(\d{3})/;
            while (rgx.test(x1)) {
                x1 = x1.replace(rgx, '$1' + ',' + '$2');
            }
            return x1 + x2;
        },
        detectIE: function () {
            const ua = window.navigator.userAgent;
            const msie = ua.indexOf('MSIE ');
            if (msie > 0) {
                // IE 10或更早版本=>返回版本号
                return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
            }
            const trident = ua.indexOf('Trident/');
            if (trident > 0) {
                // IE 11=>返回版本号
                const rv = ua.indexOf('rv:');
                return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
            }
            const edge = ua.indexOf('Edge/');
            if (edge > 0) {
                // 边缘（即12+）=>返回版本号
                return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
            }
            // 其他浏览器
            return false;
        },
        isRTL: function () {
            const html = KTUtil.getByTagName('html')[0];
            if (html) {
                return (KTUtil.attr(html, 'direction') == 'rtl');
            }
        },
        // 卷轴
        scrollInit: function (element, options) {
            if (!element) {
                return;
            }
            //完美滚动条
            const pluginDefOptions = {
                wheelSpeed: 0.5,
                swipeEasing: true,
                wheelPropagation: false,
                minScrollbarLength: 40,
                maxScrollbarLength: 300,
                suppressScrollX: true
            };
            options = KTUtil.deepExtend({}, pluginDefOptions, options);

            // 定义初始化函数
            function init() {
                let ps;
                let height;
                // 通过数据属性获取额外选项
                const attrs = element.getAttributeNames();
                if (attrs.length > 0) {
                    attrs.forEach(function (attrName) {
                        const optionName = attrName.replace('data-', '').toLowerCase().replace(/(?:[\s-])\w/g, function (match) {
                            return match.replace('-', '').toUpperCase();
                        });
                        //小滑块
                        if ((/^data-.*/g).test(attrName)) {
                            if (['scroll', 'height', 'mobile-height'].includes(optionName) == false) {
                                options[optionName] = KTUtil.filterBoolean(element.getAttribute(attrName));
                            }
                        }
                    });
                }
                if (options.height instanceof Function) {
                    height = options.height.call();
                } else {
                    if (KTUtil.isMobileDevice() === true && options.mobileHeight) {
                        height = parseInt(options.mobileHeight);
                    } else if (options.height) {
                        height = parseInt(options.height);
                    } else {
                        height = parseInt(KTUtil.css(element, 'height'));
                    }
                }
                if (height === false) {
                    KTUtil.scrollDestroy(element, true);
                    return;
                }
                height = parseInt(height);
                // 销毁桌面滚动和移动模式
                if ((options.mobileNativeScroll || options.disableForMobile) && KTUtil.isMobileDevice() === true) {
                    ps = KTUtil.data(element).get('ps');
                    if (ps) {
                        if (options.resetHeightOnDestroy) {
                            KTUtil.css(element, 'height', 'auto');
                        } else {
                            KTUtil.css(element, 'overflow', 'auto');
                            if (height > 0) {
                                KTUtil.css(element, 'height', height + 'px');
                            }
                        }
                        ps.destroy();
                        ps = KTUtil.data(element).remove('ps');
                    } else if (height > 0) {
                        KTUtil.css(element, 'overflow', 'auto');
                        KTUtil.css(element, 'height', height + 'px');
                    }
                    return;
                }
                if (height > 0) {
                    KTUtil.css(element, 'height', height + 'px');
                }
                if (options.desktopNativeScroll) {
                    KTUtil.css(element, 'overflow', 'auto');
                    return;
                }
                // 通过HTML属性传递选项
                if (KTUtil.attr(element, 'data-window-scroll') == 'true') {
                    options.windowScroll = true;
                }
                // 初始化卷轴
                ps = KTUtil.data(element).get('ps');
                if (ps) {
                    ps.update();
                } else {
                    KTUtil.css(element, 'overflow', 'hidden');
                    KTUtil.addClass(element, 'scroll');
                    ps = new window.PerfectScrollbar(element, options);
                    KTUtil.data(element).set('ps', ps);
                }
                // 记住cookie中的滚动位置
                const uid = KTUtil.attr(element, 'id');
                // Todo:考虑使用本地存储
                // eslint-disable-next-line no-undef
                if (options.rememberPosition === true && KTCookie && uid) {
                    // eslint-disable-next-line no-undef
                    if (KTCookie.getCookie(uid)) {
                        // eslint-disable-next-line no-undef
                        const pos = parseInt(KTCookie.getCookie(uid));
                        if (pos > 0) {
                            element.scrollTop = pos;
                        }
                    }
                    element.addEventListener('ps-scroll-y', function () {
                        // eslint-disable-next-line no-undef
                        KTCookie.setCookie(uid, element.scrollTop);
                    });
                }
            }

            // 初始化
            init();
            //控制窗口大小
            if (options.handleWindowResize) {
                KTUtil.addResizeHandler(function () {
                    init();
                });
            }
        },
        scrollUpdate: function (element) {
            const ps = KTUtil.data(element).get('ps');
            if (ps) {
                ps.update();
            }
        },
        scrollUpdateAll: function (parent) {
            const scrollers = KTUtil.findAll(parent, '.ps');
            let i = 0, len = scrollers.length;
            for (; i < len; i++) {
                KTUtil.scrollUpdate(scrollers[i]);
            }
        },
        scrollDestroy: function (element, resetAll) {
            let ps = KTUtil.data(element).get('ps');
            if (ps) {
                ps.destroy();
                ps = KTUtil.data(element).remove('ps');
            }
            if (element && resetAll) {
                element.style.setProperty('overflow', '');
                element.style.setProperty('height', '');
            }
        },
        filterBoolean: function (val) {
            // 转换字符串布尔值
            if (val === true || val === 'true') {
                return true;
            }
            if (val === false || val === 'false') {
                return false;
            }
            return val;
        },
        setHTML: function (el, html) {
            el.innerHTML = html;
        },
        getHTML: function (el) {
            if (el) {
                return el.innerHTML;
            }
        },
        getDocumentHeight: function () {
            const body = document.body;
            const html = document.documentElement;
            return Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
        },
        getScrollTop: function () {
            return (document.scrollingElement || document.documentElement).scrollTop;
        },
        changeColor: function (col, amt) {
            let usePound = false;
            if (col[0] == "#") {
                col = col.slice(1);
                usePound = true;
            }
            const num = parseInt(col, 16);
            let r = (num >> 16) + amt;
            if (r > 255) r = 255;
            else if (r < 0) r = 0;
            let b = ((num >> 8) & 0x00FF) + amt;
            if (b > 255) b = 255;
            else if (b < 0) b = 0;
            let g = (num & 0x0000FF) + amt;
            if (g > 255) g = 255;
            else if (g < 0) g = 0;
            return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16);
        },
        // 节流功能：作为需要节流的功能输入，延迟是以毫秒为单位的时间间隔
        throttle: function (timer, func, delay) {
            //如果已计划设置超时，则无需执行任何操作
            if (timer) {
                return;
            }
            // 在延迟秒后安排设置超时
            timer = setTimeout(function () {
                func();
                //一旦setTimeout函数执行完成，timerId=undefined，以便在<br>
                //下一个滚动事件函数的执行可以通过setTimeout进行计划
                timer = undefined;
            }, delay);
        },
        // 去抖动功能：输入为需要去抖动的功能，延迟是以毫秒为单位的去抖动时间
        debounce: function (timer, func, delay) {
            // 取消setTimeout方法的执行
            clearTimeout(timer)
            // 在延迟时间后执行func
            timer = setTimeout(func, delay);
        },
        btnWait: function (el, cls, message, disable) {
            if (!el) {
                return;
            }
            if (typeof disable !== 'undefined' && disable === true) {
                KTUtil.attr(el, "disabled", true);
            }
            if (cls) {
                KTUtil.addClass(el, cls);
                KTUtil.attr(el, "wait-class", cls);
            }
            if (message) {
                const caption = KTUtil.find(el, '.btn-caption');
                if (caption) {
                    KTUtil.data(caption).set('caption', KTUtil.getHTML(caption));
                    KTUtil.setHTML(caption, message);
                } else {
                    KTUtil.data(el).set('caption', KTUtil.getHTML(el));
                    KTUtil.setHTML(el, message);
                }
            }
        },
        btnRelease: function (el) {
            if (!el) {
                return;
            }
            // 在按钮上显示加载状态
            KTUtil.removeAttr(el, "disabled");
            if (KTUtil.hasAttr(el, "wait-class")) {
                KTUtil.removeClass(el, KTUtil.attr(el, "wait-class"));
            }
            const caption = KTUtil.find(el, '.btn-caption');
            if (caption && KTUtil.data(caption).has('caption')) {
                KTUtil.setHTML(caption, KTUtil.data(caption).get('caption'));
            } else if (KTUtil.data(el).has('caption')) {
                KTUtil.setHTML(el, KTUtil.data(el).get('caption'));
            }
        },
        isOffscreen: function (el, direction, offset) {
            offset = offset || 0;
            const windowWidth = KTUtil.getViewPort().width;
            const windowHeight = KTUtil.getViewPort().height;
            const top = KTUtil.offset(el).top;
            const height = KTUtil.outerHeight(el) + offset;
            const left = KTUtil.offset(el).left;
            const width = KTUtil.outerWidth(el) + offset;
            if (direction == 'bottom') {
                if (windowHeight < top + height) {
                    return true;
                } else if (windowHeight > top + height * 1.5) {
                    return true;
                }
            }
            if (direction == 'top') {
                if (top < 0) {
                    return true;
                } else if (top > height) {
                    return true;
                }
            }
            if (direction == 'left') {
                if (left < 0) {
                    return true;
                } else if (left * 2 > width) {
                    //console.log('left 2');
                    //return true;
                }
            }
            if (direction == 'right') {
                if (windowWidth < left + width) {
                    return true;
                } else {
                    //console.log('right 2');
                    //return true;
                }
            }
            return false;
        }
    }
}();
// 网页包支持
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    module.exports = KTUtil;
}
// 在文档就绪时初始化KTUtil类
KTUtil.ready(function () {
    if (typeof KTAppSettings !== 'undefined') {
        // eslint-disable-next-line no-undef
        KTUtil.init(KTAppSettings);
    } else {
        KTUtil.init();
    }
});
// CSS3仅在页面加载后转换（.PageLoading类添加到body标记，并在页面加载时使用JS移除）
window.onload = function () {
    const result = KTUtil.getByTagName('body');
    if (result && result[0]) {
        KTUtil.removeClass(result[0], 'page-loading');
    }
}
export default KTUtil;